package com.luxsoft.siipap.em.replica.importadores.ventas;

import java.math.BigDecimal;

import org.springframework.util.Assert;

import com.luxsoft.siipap.cxc.model.OrigenDeOperacion;
import com.luxsoft.siipap.ventas.model.Venta;
import com.luxsoft.siipap.ventas.model.VentaDet;

/**
 * Utilerias para actualizar los descuentos  en forma consistente
 * para las ventas importadas desde DBF
 * 
 * @author Ruben Cancino Ramos
 *
 */
public class DescuentosUtils {
	
	/**
	 * Permite calcular de forma adecuada los descuentos para la venta 
	 * 
	 * @param v
	 */
	public static void asignarDescuentos(final Venta v){
		for(VentaDet det:v.getPartidas()){
			BigDecimal precioLista=det.getPrecioLista();
			BigDecimal precioFacturado=det.getPrecio();
			if(precioLista.abs().doubleValue()>0){
				double descuento=precioFacturado.doubleValue()/precioLista.doubleValue();
				descuento*=100;
				det.setDescuentoOriginal(Math.abs(descuento));
				// En este caso la propiedad descuento se queda en cero
				det.setDescuento(0);
			}
		}
		//Calculamos el descuento general correcto
		double importePL=0;
		for(VentaDet det:v.getPartidas()){
			double pl=det.getPrecioLista().doubleValue();
			double cantidad=det.getCantidad()/det.getFactor();
			double impBruto=cantidad*pl;
			importePL+=impBruto;
		}
		if(importePL>0){
			double importe=v.getImporte().doubleValue();
			double res=(importePL/importe)*100;
			v.setDescuentoGeneral(res);
		}
	}
	
	
	/**
	 * Actualiza de forma adecuada los descuentos de las partidas de ventas de credito  
	 * tipo precio neto. 
	 * 
	 * Actualiza tambien el descuento general de la venta
	 * para que sea consistente con lo calculado en las partidas y util en reportes
	 * estadisticos
	 *  
	 * @param v
	 */
	public void asignarDescuentosVentaCreditoPrecioNeto(final Venta v){
		if(!v.getOrigen().equals(OrigenDeOperacion.CRE))
				return; //No es de credito
		if(v.isPrecioNeto()){
			for(VentaDet det:v.getPartidas()){
				BigDecimal precioLista=det.getPrecioLista();
				BigDecimal precioFacturado=det.getPrecio();
				if(precioLista.abs().doubleValue()>0){
					double descuento=precioFacturado.doubleValue()/precioLista.doubleValue();
					descuento*=100;
					det.setDescuentoOriginal(Math.abs(descuento));
					// En este caso la propiedad descuento se queda en cero
					det.setDescuento(0);
				}
			}
		}
		
		//Calculamos el descuento general correcto
		double importePL=0;
		for(VentaDet det:v.getPartidas()){
			double pl=det.getPrecioLista().doubleValue();
			double cantidad=det.getCantidad()/det.getFactor();
			double impBruto=cantidad*pl;
			importePL+=impBruto;
		}
		if(importePL>0){
			double importe=v.getImporte().doubleValue();
			double res=(importePL/importe)*100;
			v.setDescuentoGeneral(res);
		}
	}
	
	
	
	/**
	 * Actualiza de forma adecuada los descuentos de las partidas de ventas de credito  
	 * tipo precio bruto.
	 * 
	 * Actualiza tambien el descuento general de la venta
	 * para que sea consistente con lo calculado en las partidas y util en reportes
	 * estadisticos
	 * 
	 * @param v
	 */
	public void asignarDescuentosVentasCreditoPrecioBruto(final Venta v){
		if(!v.getOrigen().equals(OrigenDeOperacion.CRE))
			return; //No es de credito
		if(v.isPrecioBruto()){
			//Delegar a descuentos manager
		}
	}
	
	/**
	 * Actualiza de forma adecuada los descuentos de las partidas de ventas de credito  
	 * tipo cheque post fechado
	 * 
	 * Nota: Este metodo asume que el descuento general de la venta Venta.descuentoGeneral
	 * ha sido asignado de fomra correcta. 
	 * @param v
	 */
	public void asignarDescuentosVentasCreditoPostFechado(final Venta v){
		if(!v.getOrigen().equals(OrigenDeOperacion.CRE))
			return; //No es de credito
		if(v.isPostFechado()){
			double descuento=v.getDescuentoGeneral();
			for(VentaDet det:v.getPartidas()){
				det.setDescuento(descuento);
				det.setDescuentoOriginal(Math.abs(descuento)*100);
			}
		}
	}
	
	/**
	 * Actualiza los descuentos de las partidas en ventas de contado
	 *  
	 * Nota: Este metodo asume que el descuento general de la venta Venta.descuentoGeneral
	 * ha sido asignado de fomra correcta.
	 *  
	 * @param v
	 */
	public void asignarDescuentosContado(final Venta v){
		Assert.notNull(v);
		if(v.getOrigen().equals(OrigenDeOperacion.CRE))
			return; //No es de contado
		
		double descuento=v.getDescuentoGeneral();
		for(VentaDet det:v.getPartidas()){
			det.setDescuento(descuento);
			det.setDescuentoOriginal(Math.abs(descuento)*100);
		}
	}

}
